package com.tomcov.client.activities;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.ActionCell.Delegate;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.maps.client.base.ElementProvider;
import com.google.gwt.maps.client.base.HasElementProvider;
import com.google.gwt.maps.client.directions.DirectionsCallback;
import com.google.gwt.maps.client.directions.DirectionsRenderer;
import com.google.gwt.maps.client.directions.DirectionsRequest;
import com.google.gwt.maps.client.directions.DirectionsService;
import com.google.gwt.maps.client.directions.DirectionsTravelMode;
import com.google.gwt.maps.client.directions.DirectionsWaypoint;
import com.google.gwt.maps.client.directions.HasDirectionsLeg;
import com.google.gwt.maps.client.directions.HasDirectionsRequest;
import com.google.gwt.maps.client.directions.HasDirectionsResult;
import com.google.gwt.maps.client.directions.HasDirectionsService;
import com.google.gwt.maps.client.directions.HasDirectionsStep;
import com.google.gwt.maps.client.directions.HasDirectionsTravelMode;
import com.google.gwt.maps.client.directions.HasDirectionsWaypoint;
import com.google.gwt.maps.client.directions.impl.DirectionsRendererImpl;
import com.google.gwt.place.shared.Place;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.tomcov.client.ClientFactory;
import com.tomcov.client.Ressource.TomCovRes;
import com.tomcov.client.i18n.MapViewConstants;
import com.tomcov.client.view.MyJourneyView;
import com.tomcov.shared.Journey;
import com.tomcov.shared.JourneyPassenger;
import com.tomcov.shared.UserInfo;

public class MyJourneyActivity extends AbstractActivity implements MyJourneyView.Presenter{

	private ClientFactory clientFactory;


	/**
	 * Instantiates a new my journey activity.
	 *
	 * @param clientFactory the client factory
	 */
	public MyJourneyActivity(ClientFactory clientFactory){
		this.clientFactory = clientFactory;	
	}

	@Override
	public void start(AcceptsOneWidget panel, EventBus eventBus) {
		MyJourneyView MyJourneyView = clientFactory.getMyJourneyView();
		getUserInSession();
		MyJourneyView.setPresenter(this);
		panel.setWidget(MyJourneyView.asWidget());


	}

	@Override
	public void goTo(Place place) {
		clientFactory.getPlaceController().goTo(place);		
	}

	public void getUserInSession(){
		clientFactory.getUSA().getUserInSession(new AsyncCallback<UserInfo>(){
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("failtogetinsession");

			}
			@Override
			public void onSuccess(UserInfo result) {
				if(result==null){Window.alert("nobody in session");}
				else{
					GenerateCellDriver(result.getUserName());
					GenerateCellPassengerLooking(result.getUserName());
					getJourneywhereiamapassenger(result.getUserName());
				}
			}
		});
	}

	private void getJourneywhereiamapassenger(String userName) {

		clientFactory.getJPSA().getJourneyByName2(userName,new AsyncCallback<List<JourneyPassenger>>(){

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("server fail to get as passenger");
				caught.printStackTrace();
			}

			@Override
			public void onSuccess(List<JourneyPassenger> result) {
				GenerateCellPassenger(result);

			}
		});
	}

	public void GenerateCellPassenger(List<JourneyPassenger> result){
		MyJourneyView mapView = clientFactory.getMyJourneyView();
		VerticalPanel Cellcontainer=mapView.getCellpassenger();
		Cellcontainer.clear();

		if( result==null){
			MapViewConstants constants = GWT.create(MapViewConstants.class);
			TomCovRes tomtom = GWT.create(TomCovRes.class);
			HorizontalPanel pnl = new HorizontalPanel();
			Image warning = new Image(tomtom.NotOk());
			Label lb = new Label(constants.noJourneyasPassenger());
			lb.addStyleName("label");
			pnl.add(warning);
			pnl.add(lb);
			pnl.addStyleName("warningpanel");
			Cellcontainer.add(pnl);
		}
		else{
			
			MapViewConstants tomtom = GWT.create(MapViewConstants.class);
			
			CellTable<JourneyPassenger> celltable = new CellTable<JourneyPassenger>();
			celltable.setPageSize(5);

			TextColumn<JourneyPassenger> DriverColumn = new TextColumn<JourneyPassenger>() {
				@Override
				public String getValue(JourneyPassenger object) {
					return object.getDriverName();
				}
			};
			celltable.addColumn(DriverColumn, tomtom.driver());
			DriverColumn.setSortable(true);

			DateCell dateCell = new DateCell();
			Column<JourneyPassenger,Date> DateColumn = new Column<JourneyPassenger,Date>(dateCell) {
				@Override
				public Date getValue(JourneyPassenger object) {
					return object.date;
				}
			};
			celltable.addColumn(DateColumn, tomtom.Date());
			DateColumn.setSortable(true);
			
			TextColumn<JourneyPassenger> FromColumn = new TextColumn<JourneyPassenger>() {
				@Override
				public String getValue(JourneyPassenger object) {
					return object.From;
				}
			};
			celltable.addColumn(FromColumn,tomtom.from());
			FromColumn.setSortable(true);

			TextColumn<JourneyPassenger> ToColumn = new TextColumn<JourneyPassenger>() {
				@Override
				public String getValue(JourneyPassenger object) {
					return object.To;
				}
			};
			celltable.addColumn(ToColumn, tomtom.to());
			ToColumn.setSortable(true);

			SimplePager pager = new SimplePager();
			pager.setDisplay(celltable);
			Cellcontainer.add(pager);
			Cellcontainer.add(celltable);

			ListDataProvider<JourneyPassenger> dataProvider = new ListDataProvider<JourneyPassenger>();
			// Connect the table to the data provider.
			dataProvider.addDataDisplay(celltable);
			List<JourneyPassenger> list = dataProvider.getList();
			for (JourneyPassenger contact :  result) {
				list.add(contact);
			}

			ListHandler<JourneyPassenger> FromcolumnSortHandler = new ListHandler<JourneyPassenger>(list);
			FromcolumnSortHandler.setComparator(FromColumn,
					new Comparator<JourneyPassenger>() {
				public int compare(JourneyPassenger o1, JourneyPassenger o2) {
					if (o1 == o2) {return 0;}
					if (o1 != null) {return (o2 != null) ? o1.From.compareTo(o2.From) : 1;}
					return -1;
				}
			});

			ListHandler<JourneyPassenger> TocolumnSortHandler = new ListHandler<JourneyPassenger>(list);
			TocolumnSortHandler.setComparator(ToColumn,
					new Comparator<JourneyPassenger>() {
				public int compare(JourneyPassenger o1, JourneyPassenger o2) {
					if (o1 == o2) {return 0;}
					if (o1 != null) {return (o2 != null) ? o1.To.compareTo(o2.To) : 1;}
					return -1;
				}
			});

			ListHandler<JourneyPassenger> DatecolumnSortHandler = new ListHandler<JourneyPassenger>(list);
			DatecolumnSortHandler.setComparator(DateColumn,
					new Comparator<JourneyPassenger>() {
				public int compare(JourneyPassenger o1, JourneyPassenger o2) {
					if (o1 == o2) {return 0;}
					if (o1 != null) {return (o2 != null) ? o1.date.compareTo(o2.date) : 1;}
					return -1;
				}
			});

			ListHandler<JourneyPassenger> DrivercolumnSortHandler = new ListHandler<JourneyPassenger>(list);
			DatecolumnSortHandler.setComparator(DriverColumn,
					new Comparator<JourneyPassenger>() {
				public int compare(JourneyPassenger o1, JourneyPassenger o2) {
					if (o1 == o2) {return 0;}
					if (o1 != null) {return (o2 != null) ? o1.getDriverName().compareTo(o2.getDriverName()) : 1;}
					return -1;
				}
			});


			celltable.addColumnSortHandler(FromcolumnSortHandler);
			celltable.addColumnSortHandler(TocolumnSortHandler);
			celltable.addColumnSortHandler(DatecolumnSortHandler);
			celltable.addColumnSortHandler(DrivercolumnSortHandler);

		}

	}

	public void GenerateCellDriver(String username){


		clientFactory.getJSA().getJounreyAsDriver(username, new AsyncCallback<List<Journey>>(){
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("serveur fail");
				caught.printStackTrace();
			}
			@Override
			public void onSuccess(List<Journey> result) {
				VerticalPanel Cellcontainer=clientFactory.getMyJourneyView().getCellDriver();
				CellTable<Journey> celltable = new CellTable<Journey>();
				Cellcontainer.clear();
				celltable.setPageSize(5);
				if (result==null){
					MapViewConstants constants = GWT.create(MapViewConstants.class);
					TomCovRes tomtom = GWT.create(TomCovRes.class);
					HorizontalPanel pnl = new HorizontalPanel();
					Image warning = new Image(tomtom.NotOk());
					Label lb = new Label(constants.noJourneyasDriver());
					lb.addStyleName("label");
					pnl.add(warning);
					pnl.add(lb);
					pnl.addStyleName("warningpanel");
					Cellcontainer.add(pnl);
				}
				else{
					
					MapViewConstants tomtom = GWT.create(MapViewConstants.class);
					
					TextColumn<Journey> DriverColumn = new TextColumn<Journey>() {
						@Override
						public String getValue(Journey object) {
							return object.Driver;
						}
					};
					celltable.addColumn(DriverColumn, tomtom.driver());
					DriverColumn.setSortable(true);				

					DateCell dateCell = new DateCell();
					Column<Journey,Date> DateColumn = new Column<Journey,Date>(dateCell) {
						@Override
						public Date getValue(Journey object) {
							return object.date;
						}
					};
					celltable.addColumn(DateColumn, tomtom.Date());
					DateColumn.setSortable(true);

					TextColumn<Journey> FromColumn = new TextColumn<Journey>() {
						@Override
						public String getValue(Journey object) {
							return object.From;
						}
					};
					celltable.addColumn(FromColumn, tomtom.from());
					FromColumn.setSortable(true);

					TextColumn<Journey> ToColumn = new TextColumn<Journey>() {
						@Override
						public String getValue(Journey object) {
							return object.To;
						}
					};
					celltable.addColumn(ToColumn, tomtom.to());
					ToColumn.setSortable(true);

					SimplePager pager = new SimplePager();
					pager.setDisplay(celltable);
					Cellcontainer.add(pager);
					Cellcontainer.add(celltable);


					ListDataProvider<Journey> dataProvider = new ListDataProvider<Journey>();

					// Connect the table to the data provider.
					dataProvider.addDataDisplay(celltable);

					List<Journey> list = dataProvider.getList();
					for (Journey contact :  result) {
						list.add(contact);
					}

					ListHandler<Journey> DatecolumnSortHandler = new ListHandler<Journey>(list);
					DatecolumnSortHandler.setComparator(DateColumn,
							new Comparator<Journey>() {
						public int compare(Journey o1, Journey o2) {
							if (o1 == o2) {return 0;}
							if (o1 != null) {return (o2 != null) ? o1.date.compareTo(o2.date) : 1;}
							return -1;
						}
					});
					celltable.addColumnSortHandler(DatecolumnSortHandler);
					celltable.getColumnSortList().push(DateColumn);
					celltable.addColumn( new Column<Journey, List<String>>(new ActionCell<List<String>>( "Show Passenger", new Delegate<List<String>>( )
							{@Override
						public void execute(List<String> object) {
								String t="";
								for(int i=0;i<object.size();i++){
									t=t+object.get(i)+"\n";
								}
								Window.alert(t);
							}
							}))
							{@Override
						public List<String> getValue(Journey object) {
								return object.getPassengerList();
							}
							} );
					celltable.addColumn( new Column<Journey,Journey>(new ActionCell<Journey>( "Delete", 
							new Delegate<Journey>( ){
						@Override
						public void execute(Journey object) {
							clientFactory.getJSA().delete(object, new AsyncCallback<Journey>(){
								@Override
								public void onFailure(Throwable caught) {
									Window.alert("not deleted");
									caught.printStackTrace();
								}
								@Override
								public void onSuccess(Journey result) {
									Window.alert("journey deleted");
									getUserInSession();
								}
							});
						}
					}))
					{@Override
						public Journey getValue(Journey Journey) {
						return Journey;
					}
					} );

					celltable.addColumn( new Column<Journey, Journey>(new ActionCell<Journey>( tomtom.getRoad(), new 
							Delegate<Journey>(){
						@Override
						public void execute(Journey object) {
							getroad(object);
							
							}
							}))
							{@Override
						public Journey getValue(Journey object) {
								return object;
							}
							} );
				}

			}
		});
	}

	public void GenerateCellPassengerLooking(String username){
		clientFactory.getJPSA().getJourneyByName(username, new AsyncCallback<List<JourneyPassenger>>(){

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("serveur fail");
				caught.printStackTrace();
			}

			@Override
			public void onSuccess(List<JourneyPassenger> result) {
				VerticalPanel Cellcontainer = clientFactory.getMyJourneyView().getCellPassengerLooking();
				Cellcontainer.clear();
				if(result==null){
					MapViewConstants constants = GWT.create(MapViewConstants.class);
					TomCovRes tomtom = GWT.create(TomCovRes.class);
					HorizontalPanel pnl = new HorizontalPanel();
					Image warning = new Image(tomtom.NotOk());
					Label lb = new Label(constants.nopassengerfound());
					lb.addStyleName("label");
					pnl.add(warning);
					pnl.add(lb);
					pnl.addStyleName("warningpanel");
					Cellcontainer.add(pnl);
				}
				else{
					
					MapViewConstants tomtom = GWT.create(MapViewConstants.class);
					
					CellTable<JourneyPassenger> celltable = new CellTable<JourneyPassenger>();
					celltable.setPageSize(5);

					TextColumn<JourneyPassenger> DriverColumn = new TextColumn<JourneyPassenger>() {
						@Override
						public String getValue(JourneyPassenger object) {
							return object.Passenger;
						}
					};
					celltable.addColumn(DriverColumn,tomtom.passenger());
					DriverColumn.setSortable(true);

					TextColumn<JourneyPassenger> FromColumn = new TextColumn<JourneyPassenger>() {
						@Override
						public String getValue(JourneyPassenger object) {
							return object.From;
						}
					};
					celltable.addColumn(FromColumn, tomtom.from());
					FromColumn.setSortable(true);

					TextColumn<JourneyPassenger> ToColumn = new TextColumn<JourneyPassenger>() {
						@Override
						public String getValue(JourneyPassenger object) {
							return object.To;
						}
					};
					celltable.addColumn(ToColumn, tomtom.to());
					ToColumn.setSortable(true);

					DateCell dateCell = new DateCell();
					Column<JourneyPassenger,Date> DateColumn = new Column<JourneyPassenger,Date>(dateCell) {
						@Override
						public Date getValue(JourneyPassenger object) {
							return object.date;
						}
					};
					celltable.addColumn(DateColumn, tomtom.Date());
					DateColumn.setSortable(true);


					SimplePager pager = new SimplePager();
					pager.setDisplay(celltable);
					Cellcontainer.add(pager);
					Cellcontainer.add(celltable);

					ListDataProvider<JourneyPassenger> dataProvider = new ListDataProvider<JourneyPassenger>();
					// Connect the table to the data provider.
					dataProvider.addDataDisplay(celltable);
					List<JourneyPassenger> list = dataProvider.getList();
					for (JourneyPassenger contact :  result) {
						list.add(contact);
					}

					ListHandler<JourneyPassenger> FromcolumnSortHandler = new ListHandler<JourneyPassenger>(list);
					FromcolumnSortHandler.setComparator(FromColumn,
							new Comparator<JourneyPassenger>() {
						public int compare(JourneyPassenger o1, JourneyPassenger o2) {
							if (o1 == o2) {return 0;}
							if (o1 != null) {return (o2 != null) ? o1.From.compareTo(o2.From) : 1;}
							return -1;
						}
					});
					ListHandler<JourneyPassenger> TocolumnSortHandler = new ListHandler<JourneyPassenger>(list);
					TocolumnSortHandler.setComparator(ToColumn,
							new Comparator<JourneyPassenger>() {
						public int compare(JourneyPassenger o1, JourneyPassenger o2) {
							if (o1 == o2) {return 0;}
							if (o1 != null) {return (o2 != null) ? o1.To.compareTo(o2.To) : 1;}
							return -1;
						}
					});
					ListHandler<JourneyPassenger> DatecolumnSortHandler = new ListHandler<JourneyPassenger>(list);
					DatecolumnSortHandler.setComparator(DateColumn,
							new Comparator<JourneyPassenger>() {
						public int compare(JourneyPassenger o1, JourneyPassenger o2) {
							if (o1 == o2) {return 0;}
							if (o1 != null) {return (o2 != null) ? o1.date.compareTo(o2.date) : 1;}
							return -1;
						}
					});

					ListHandler<JourneyPassenger> DrivercolumnSortHandler = new ListHandler<JourneyPassenger>(list);
					DatecolumnSortHandler.setComparator(DriverColumn,
							new Comparator<JourneyPassenger>() {
						public int compare(JourneyPassenger o1, JourneyPassenger o2) {
							if (o1 == o2) {return 0;}
							if (o1 != null) {return (o2 != null) ? o1.Passenger.compareTo(o2.Passenger) : 1;}
							return -1;
						}
					});


					celltable.addColumnSortHandler(FromcolumnSortHandler);
					celltable.addColumnSortHandler(TocolumnSortHandler);
					celltable.addColumnSortHandler(DatecolumnSortHandler);
					celltable.addColumnSortHandler(DrivercolumnSortHandler);


					celltable.addColumn( new Column<JourneyPassenger,JourneyPassenger>(new ActionCell<JourneyPassenger>( "Delete", 
							new Delegate<JourneyPassenger>( ){
						public void execute(JourneyPassenger object) {
							clientFactory.getJPSA().delete(object.getId(), new AsyncCallback<JourneyPassenger>(){
								@Override
								public void onFailure(Throwable caught) {
									Window.alert("not deleted");
								}
								@Override
								public void onSuccess(JourneyPassenger result) {
									Window.alert("journey deleted");
									getUserInSession();

								}
							});
						}
					}))
					{@Override
						public JourneyPassenger getValue(JourneyPassenger Journey) {
						return Journey;
					}
					} );


				}
			}
		});
	}

	private String MapUrl;

	public void getroad(Journey journey){
		final DirectionsRenderer directionsRenderer = new DirectionsRenderer();
		HasDirectionsService directionsService = new DirectionsService();
		MyJourneyView myJourneyView = clientFactory.getMyJourneyView();
		MapUrl="";
		myJourneyView.getDirPanel().clear();

		DirectionsRendererImpl.impl.setMap(directionsRenderer.getJso(),null);
		HasElementProvider element = new ElementProvider(myJourneyView.getDirPanel().getElement());
		directionsRenderer.setPanel(element);
		HasDirectionsRequest directionsRequest = new DirectionsRequest();
		HasDirectionsTravelMode travelMode = new DirectionsTravelMode();
		directionsRequest.setTravelMode(travelMode.Driving());
		directionsRequest.setOriginString(journey.getFrom());
		directionsRequest.setDestinationString(journey.getTo());

		if(journey.getWaypoints().size()!=0 || journey.getWaypoints()!=null){
			ArrayList<HasDirectionsWaypoint> waypoints = new ArrayList<HasDirectionsWaypoint>();
			for(int l =0;l<journey.getWaypoints().size();l+=2){
				HasDirectionsWaypoint point = new DirectionsWaypoint();
				HasDirectionsWaypoint point1 = new DirectionsWaypoint();
				point.setLocation(journey.getWaypoints().get(l));
				point1.setLocation(journey.getWaypoints().get(l+1));
				waypoints.add(point);
				waypoints.add(point1);				
			}
			directionsRequest.setWaypoints(waypoints);
		}


		directionsService.route(directionsRequest, new DirectionsCallback() {
			@Override
			public void callback(HasDirectionsResult response, String status) {
				directionsRenderer.setDirections(response);
				List<String> steps = new ArrayList<String>();
				for (HasDirectionsLeg leg : response.getRoutes().get(0).getLegs()) {
					for (HasDirectionsStep step : leg.getSteps()) {
						for (int j = 0; j < step.getPath().size(); j = j + 4) {
							steps.add(step.getPath().get(j).toUrlValue());
						}
					}
				}

				MapUrl = "http://maps.google.com/maps/api/staticmap?size=500x500&path=color:0x0000ff";
				for (String step : steps) {
					MapUrl = MapUrl+ "%7C" + step;
				}
				MapUrl = MapUrl+ "&sensor=false";
				Window.open(MapUrl,"mozilla",null);
			}
		});


	}

}

